package org.xxpay.pay.channel.simplepay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Service;
import org.xxpay.common.util.str.StringUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.entity.PayOrder;

import org.xxpay.pay.channel.BasePayment;
import org.xxpay.pay.channel.simplepay.util.HttpClick;


import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

@Service
public class SimplepayPaymentService extends BasePayment {
    @Override
    public String getChannelName() { return SimplepayPayConfig.CHANNEL_NAME; }
    @Override
    public JSONObject pay(PayOrder payOrder) {
        //String channelId = payOrder.getChannelId();
        JSONObject retObj;
//        switch (channelId) {
//            case SimplepayPayConfig.CHANNEL_NAME_SIMPLEPAY_ALIPAY_QR:
//                retObj = doOrderReq(payOrder,1);
//                break;
//            case SimplepayPayConfig.CHANNEL_NAME_SIMPLEPAY_WX_QR:
//                retObj = doOrderReq(payOrder,3);
//                break;
//                default:
//                    retObj = buildRetObj(PayConstant.RETURN_VALUE_FAIL, "不支持的渠道[channelId="+channelId+"]");
//                    break;
//        }
        SimplepayPayConfig config = new SimplepayPayConfig(getPayParam(payOrder));
        retObj = doOrderReq(payOrder,config);
        return retObj;
    }
    /**
     * 查询订单
     * @param payOrder
     * @return
     */
    @Override
    public JSONObject query(PayOrder payOrder) {
        JSONObject retObj = buildRetObj();
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, "没有订单查询接口");
        return retObj;
    }


    //下单请求实现
    private JSONObject doOrderReq(PayOrder payOrder,SimplepayPayConfig config){
//        SimplepayPayConfig config = new SimplepayPayConfig(getPayParam(payOrder));
        Map<String,Object> parameters = Maps.newHashMap();
        //设置参数
        setParames(payOrder,config,parameters);
        //配置请求参数
        String id = config.getAppId();
        String nonce = parameters.get("nonce").toString();
        String url = config.getRequestUrl()+"?id="+id+ "&nonce="+nonce;
        String body = getData(parameters);
        _log.info("{}请求数据:{}", getChannelName(), body+";requestUrl:"+url);
        rpcCommonService.rpcPayOrderService.updateStatus4Ing(payOrder.getPayOrderId(), null);
        String res = null;
        try {
            res = HttpClick.sendHttpPost(url,body,getSign(parameters,config));
        } catch (Exception e) {
            e.printStackTrace();
        }
        _log.info("{}响应数据:{}", getChannelName(), res);
        JSONObject result = JSONObject.parseObject(res);
        JSONObject data = result.getJSONObject("data");
        JSONObject retObj = new JSONObject();
        if(StringUtils.equals(result.getString("code"),"2000")) {
            return buildPayResultOfForm(retObj, payOrder,"<script type=\"text/javascript\">\n" +
                    "　　window.location.href=\""+ data.getString("payUrl")+"\";\n" +
                    "　　</script>","data" );
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, result.toJSONString());
        return retObj;
    }

    private void setParames(PayOrder payOrder,SimplepayPayConfig config,Map<String,Object> parameters){
        parameters.put("customerOrderId", payOrder.getPayOrderId());
        parameters.put("payMode", Integer.parseInt(config.getPayMode()));
//        if(payType==3){
//            parameters.put("channelId","355055522681982976");
//        }else {
//            parameters.put("channelId", "332913618779639808");
//        }
        if(!StringUtils.equals(null,config.getPartnerId())&&config.getPartnerId().length()>0){
            parameters.put("channelId",config.getPartnerId());
        }
        // parameters.put("channelId",channelId);
        parameters.put("amount", payOrder.getAmount());
        parameters.put("callbackUrl", payConfig.getNotifyUrl(getChannelName()));

        parameters.put("attach", payOrder.getPayOrderId());
        parameters.put("payer", payOrder.getPayOrderId());
        parameters.put("nonce", System.currentTimeMillis());
    }
    /**
     * 获取请求报文
     * @param params
     * @return
     */
    private String getData(Map<String,Object> params){
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(params));
        jsonObject.remove("nonce");
        String data = jsonObject.toJSONString();
        return data;
    }

    /**
     * 获取sign
     * @param params
     * @return
     */
    private String getSign(Map<String,Object> params,SimplepayPayConfig config){
        String data = getData(params);

        String contents =config.getAppId()+params.get("nonce").toString()+data;
        String sign=null;
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(config.getPrivateKey().getBytes(),"HmacSHA256"));
            byte[] result = mac.doFinal(contents.getBytes());
            sign = bytesToHexString(result);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }
        return sign;
    }
    private  String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    protected JSONObject buildPayResultOfForm(JSONObject retObj, PayOrder payOrder, String payForm,String sdk_url) {
        // 设置支付订单ID
        retObj.put("payOrderId", payOrder.getPayOrderId());
        // 具体付款内容
        JSONObject payInfo = new JSONObject();
        payInfo.put("payUrl",payForm);
        retObj.put("sdk_url", sdk_url);
        payInfo.put("payMethod",PayConstant.PAY_METHOD_FORM_JUMP);
        retObj.put("payParams", payInfo);
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_SUCCESS);
        return retObj;
    }
}
